package org.xtremeobjects.domain.model.java5;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;

import org.xtremeobjects.domain.model.Association;
import org.xtremeobjects.domain.model.Clazz;
import org.xtremeobjects.domain.model.ClazzRepository;

class AssociationJava5 implements Association {

	private String name;
	private ClazzJava5 clazz;
	private Method getter;
	private Method setter;
	private ClazzRepository clazzRepository;

	AssociationJava5(ClazzJava5 clazz, String associationName, Method getter, Method setter, ClazzRepository clazzRepository) {
		this.clazzRepository = clazzRepository;
		this.clazz = clazz;
		this.name = associationName;
		this.getter = getter;
		this.setter = setter;
	}

	/* (non-Javadoc)
	 * @see org.xtremeobjects.domain.model.IAssociation#getName()
	 */
	public String getName() {
		return name;
	}

	public Collection<?> getCollection(Object obj) {
		Collection<?> ret = null;
		try {
			ret = (Collection<?>)getter.invoke(obj, (Object[])null);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return ret;
	}

	public AssociationType getAssociationType() {
		return getter.isAnnotationPresent(org.xtremeobjects.anotations.association.Association.class)? AssociationType.ASSOCIATION:AssociationType.AGREGATION;
	}

	/**
	 * Returns the class of the other end of the association. 
	 */
	public Clazz getToClazz() {

		//FIXME Get Class of association derivated from generic
		// collection
//		Class collection = getter.getReturnType();
		
		Class<?> cl = getClassFromAnnotation();
		return clazzRepository.findOrCreateByClass(cl);
	}

	private Class<?> getClassFromAnnotation() {
		return getAssociationAnnotation().to();
	}
	
	private org.xtremeobjects.anotations.association.Association getAssociationAnnotation() {
		return getter.getAnnotation(org.xtremeobjects.anotations.association.Association.class);
	}
	
}
